
# -*- coding: utf-8 -*-
"""
Markdown转换器应用程序

这个文件使用PyQt6框架实现了Markdown转换器的图形界面，
负责初始化主窗口并创建MarkdownConverterApp应用实例。
"""
# 导入PyQt6库，用于创建GUI界面
from PyQt6.QtWidgets import (
    QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, 
    QLabel, QLineEdit, QPushButton, QCheckBox, QProgressBar, 
    QFileDialog, QMessageBox, QFrame
)
from PyQt6.QtCore import Qt, QCoreApplication
from PyQt6.QtGui import QIcon, QFont
# 导入markitdown库，用于文件转换
from markitdown import MarkItDown
import os
import sys

class MarkdownConverterApp(QMainWindow):
    """Markdown转换器应用类
    负责创建GUI界面并处理文件转换逻辑"""
    def __init__(self):
        """初始化应用程序"""
        super().__init__()
        
        # 设置窗口属性
        self.setWindowTitle("Markdown 转换器")
        self.resize(650, 450)
        self.setMinimumSize(600, 400)  # 设置最小窗口尺寸
        
        # 应用程序样式表 - 现代UI设计
        self.setStyleSheet("""
            /* 主窗口背景 */
            QMainWindow {
                background-color: #f5f5f7;
            }
            
            /* 按钮样式 */
            QPushButton {
                background-color: #0071e3;
                color: white;
                border: none;
                border-radius: 8px;
                padding: 8px 16px;
                font-weight: 500;
                font-size: 14px;
            }
            
            QPushButton:hover {
                background-color: #0077ed;
            }
            
            QPushButton:pressed {
                background-color: #0066cc;
            }
            
            /* 文件选择按钮特殊样式 */
            #browseButton {
                background-color: #e5e5ea;
                color: #333;
                min-width: 80px;
            }
            
            #browseButton:hover {
                background-color: #d1d1d6;
            }
            
            /* 输入框样式 */
            QLineEdit {
                background-color: white;
                border: 1px solid #d1d1d6;
                border-radius: 6px;
                padding: 6px 10px;
                font-size: 14px;
            }
            
            QLineEdit:focus {
                border-color: #0071e3;
                outline: none;
            }
            
            /* 标签样式 */
            QLabel {
                font-size: 14px;
                color: #333;
            }
            
            /* 选项框样式 */
            QCheckBox {
                font-size: 14px;
                color: #333;
                spacing: 8px;
            }
            
            QCheckBox::indicator {
                width: 18px;
                height: 18px;
                border-radius: 4px;
                border: 1px solid #d1d1d6;
            }
            
            QCheckBox::indicator:checked {
                background-color: #0071e3;
                border-color: #0071e3;
            }
            
            /* 进度条样式 */
            QProgressBar {
                height: 10px;
                border-radius: 5px;
                background-color: #e5e5ea;
                text-align: center;
            }
            
            QProgressBar::chunk {
                background-color: #0071e3;
                border-radius: 5px;
            }
            
            /* 选项框区域 */
            #optionsFrame {
                background-color: white;
                border: 1px solid #d1d1d6;
                border-radius: 8px;
            }
            
            /* 状态文本颜色 */
            #statusText {
                color: #0071e3;
                font-weight: 500;
            }
            
            #statusText.error {
                color: #ff3b30;
            }
            
            #statusText.success {
                color: #34c759;
            }
        """)
        
        # 设置窗口图标
        self._setup_window_icon()
        
        # 设置中文字体支持
        self._setup_font()
        
        # 创建GUI界面
        self._init_ui()
    
    def _setup_window_icon(self):
        """设置窗口图标"""
        try:
            # 获取项目根目录（src目录的父目录）
            project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
            icon_path = os.path.join(project_root, 'app_icon.png')
            if os.path.exists(icon_path):
                self.setWindowIcon(QIcon(icon_path))
                print(f"成功加载图标: {icon_path}")
            else:
                print(f"图标文件不存在: {icon_path}")
        except Exception as e:
            # 输出详细的错误信息以便调试
            print(f"加载图标失败: {str(e)}")
            import traceback
            traceback.print_exc()
    
    def _setup_font(self):
        """设置中文字体支持"""
        font = QFont("Microsoft YaHei", 10)
        QApplication.setFont(font)
    
    def _init_ui(self):
        """初始化用户界面组件"""
        # 创建中央部件并设置布局
        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        main_layout = QVBoxLayout(central_widget)
        main_layout.setContentsMargins(20, 20, 20, 20)
        main_layout.setSpacing(15)  # 统一设置间距
        
        # 应用标题
        title_label = QLabel("Markdown 转换工具")
        title_label.setFont(QFont("Microsoft YaHei", 16, QFont.Weight.Bold))
        title_label.setStyleSheet("color: #1d1d1f; margin-bottom: 10px;")
        main_layout.addWidget(title_label, alignment=Qt.AlignmentFlag.AlignCenter)
        
        # 源文件路径选择区域
        file_label = QLabel("源文件:")
        file_label.setAlignment(Qt.AlignmentFlag.AlignLeft)
        main_layout.addWidget(file_label)
        
        file_frame = QWidget()
        file_layout = QHBoxLayout(file_frame)
        file_layout.setContentsMargins(0, 0, 0, 0)
        file_layout.setSpacing(8)
        
        # 文件路径输入框和浏览按钮
        self.file_path_edit = QLineEdit()
        browse_button = QPushButton("浏览...")
        browse_button.setObjectName("browseButton")
        browse_button.clicked.connect(self.browse_file)
        
        file_layout.addWidget(self.file_path_edit, 1)  # 1表示占用剩余空间
        file_layout.addWidget(browse_button)
        main_layout.addWidget(file_frame)
        
        # 转换选项区域
        options_frame = QFrame()
        options_frame.setObjectName("optionsFrame")
        options_frame.setFrameShape(QFrame.Shape.StyledPanel)
        options_layout = QVBoxLayout(options_frame)
        options_layout.setContentsMargins(15, 15, 15, 15)
        options_layout.setSpacing(12)
        
        # 选项标题
        options_label = QLabel("转换选项")
        options_label.setFont(QFont("Microsoft YaHei", 12, QFont.Weight.Medium))
        options_layout.addWidget(options_label)
        
        # 启用插件选项
        self.enable_plugins_check = QCheckBox("启用插件")
        self.enable_plugins_check.setChecked(False)
        
        # 保留数据URI选项
        self.keep_data_uris_check = QCheckBox("保留数据 URI")
        self.keep_data_uris_check.setChecked(False)
        
        options_layout.addWidget(self.enable_plugins_check)
        options_layout.addWidget(self.keep_data_uris_check)
        main_layout.addWidget(options_frame)
        
        # 转换按钮
        convert_button = QPushButton("开始转换")
        convert_button.setMinimumHeight(40)
        convert_button.clicked.connect(self.convert_file)
        main_layout.addWidget(convert_button, alignment=Qt.AlignmentFlag.AlignCenter)
        
        # 状态显示区域
        status_label = QLabel("状态:")
        status_label.setAlignment(Qt.AlignmentFlag.AlignLeft)
        main_layout.addWidget(status_label)
        
        self.status_text = QLabel("就绪")
        self.status_text.setObjectName("statusText")
        self.status_text.setAlignment(Qt.AlignmentFlag.AlignLeft)
        self.status_text.setWordWrap(True)  # 支持自动换行
        main_layout.addWidget(self.status_text)
        
        # 进度条
        self.progress_bar = QProgressBar()
        self.progress_bar.setRange(0, 100)
        self.progress_bar.setValue(0)
        main_layout.addWidget(self.progress_bar)
    
    def browse_file(self):
        """打开文件选择对话框
        让用户选择要转换的文件，并更新文件路径输入框
        """
        # 定义支持的文件类型
        file_types = """
        所有支持的文件 (*.epub *.pdf *.docx *.pptx *.xlsx *.jpg *.jpeg *.png *.gif *.mp3 *.wav *.csv *.json *.xml *.zip *.md *.html);;
        EPUB 文件 (*.epub);;
        PDF 文件 (*.pdf);;Word 文件 (*.docx);;
        PowerPoint 文件 (*.pptx);;
        Excel 文件 (*.xlsx);;
        图片文件 (*.jpg *.jpeg *.png *.gif);;
        音频文件 (*.mp3 *.wav);;
        文本格式文件 (*.csv *.json *.xml);;
        ZIP 文件 (*.zip);;
        HTML 文件 (*.html);;
        Markdown 文件 (*.md);;
        所有文件 (*.*)
        """
        
        # 打开文件选择对话框
        file_path, _ = QFileDialog.getOpenFileName(
            self, "选择要转换的文件", "", file_types
        )
        
        if file_path:
            # 更新文件路径输入框和状态信息
            self.file_path_edit.setText(file_path)
            self.status_text.setText(f"已选择文件: {os.path.basename(file_path)}")
            self.status_text.setStyleSheet("color: #0071e3;")
    
    def convert_file(self):
        """执行文件转换
        检查文件路径有效性，初始化转换器，执行转换并保存结果
        """
        # 获取文件路径并检查有效性
        file_path = self.file_path_edit.text()
        if not file_path or not os.path.exists(file_path):
            QMessageBox.critical(self, "错误", "请选择有效的文件")
            return
        
        try:
            # 更新状态和进度条
            self.status_text.setText("正在初始化转换器...")
            self.status_text.setStyleSheet("color: #0071e3;")
            self.progress_bar.setValue(10)
            QCoreApplication.processEvents()  # 强制更新UI
            
            # 检查文件格式是否支持
            file_ext = os.path.splitext(file_path)[1].lower()
            supported_extensions = ['.epub', '.pdf', '.docx', '.pptx', '.xlsx', 
                                   '.jpg', '.jpeg', '.png', '.gif', '.mp3', '.wav', 
                                   '.csv', '.json', '.xml', '.zip', '.md', '.html']
            
            if file_ext not in supported_extensions:
                self.status_text.setText(f"不支持的文件格式: {file_ext}")
                self.status_text.setStyleSheet("color: #ff3b30;")
                QMessageBox.warning(self, "警告", 
                                    f"当前版本可能不完全支持 {file_ext} 格式的文件转换。\n"
                                    "请尝试其他文件格式，或等待未来版本优化。")
                self.progress_bar.setValue(0)
                return
            
            # 初始化 MarkItDown 转换器
            enable_plugins = self.enable_plugins_check.isChecked()
            md = MarkItDown(enable_plugins=enable_plugins)
            
            # 更新状态和进度条
            self.status_text.setText("正在转换文件...")
            self.status_text.setStyleSheet("color: #0071e3;")
            self.progress_bar.setValue(30)
            QCoreApplication.processEvents()
            
            # 执行文件转换
            keep_data_uris = self.keep_data_uris_check.isChecked()
            result = md.convert(file_path, keep_data_uris=keep_data_uris)
            
            # 更新状态和进度条
            self.status_text.setText("正在准备保存...")
            self.status_text.setStyleSheet("color: #0071e3;")
            self.progress_bar.setValue(70)
            QCoreApplication.processEvents()
            
            # 让用户选择保存位置
            default_filename = os.path.splitext(os.path.basename(file_path))[0] + ".md"
            save_path, _ = QFileDialog.getSaveFileName(
                self,
                "保存 Markdown 文件",
                default_filename,
                "Markdown 文件 (*.md);;所有文件 (*.*)"
            )
            
            if save_path:
                # 保存转换后的Markdown内容
                with open(save_path, "w", encoding="utf-8") as f:
                    f.write(result.text_content)
                
                # 更新状态和进度条，显示成功消息
                self.status_text.setText(f"转换完成! 文件已保存到: {save_path}")
                self.status_text.setStyleSheet("color: #34c759;")
                self.progress_bar.setValue(100)
                QMessageBox.information(self, "成功", f"文件已成功转换并保存到:\n{save_path}")
            else:
                # 用户取消保存
                self.status_text.setText("转换已取消")
                self.status_text.setStyleSheet("color: #ff3b30;")
                self.progress_bar.setValue(0)
        
        except Exception as e:
            # 处理转换过程中的错误
            error_msg = str(e)
            self.status_text.setText(f"转换失败: {error_msg[:100]}...")
            self.status_text.setStyleSheet("color: #ff3b30;")
            self.progress_bar.setValue(0)
            
            # 根据错误类型提供更具体的提示
            user_error_msg = f"转换过程中发生错误:\n{error_msg[:200]}..."
            if "XlsxConverter" in error_msg:
                user_error_msg = "Excel文件转换失败。\n"
                user_error_msg += "这可能是由于文件格式复杂或包含不支持的公式。\n"
                user_error_msg += "建议: 尝试将Excel文件另存为CSV格式后再进行转换。"
            elif "FileConversionException" in error_msg:
                user_error_msg = "文件转换失败。\n"
                user_error_msg += "这可能是由于文件格式不兼容或文件已损坏。"
            
            QMessageBox.critical(self, "错误", user_error_msg)
            # 输出详细的错误信息到控制台
            print(f"转换过程中发生错误: {error_msg}")
            import traceback
            traceback.print_exc()

# 主程序入口函数
def main():
    """应用程序主入口函数"""
    # 启用高DPI支持
    QApplication.setApplicationName("Markdown转换器")
    QApplication.setOrganizationName("my-markdown-converter")
    
    # 创建QApplication实例
    app = QApplication(sys.argv)
    
    # 创建MarkdownConverterApp应用实例
    window = MarkdownConverterApp()
    
    # 显示窗口
    window.show()
    
    # 启动应用程序的主事件循环
    sys.exit(app.exec())

# 主程序入口
if __name__ == "__main__":
    main()